package com.itdct.onflow.generator.template

import com.itdct.onflow.generator.base.BaseTemplate
import com.itdct.onflow.generator.config.GeneratorConfig
import com.itdct.onflow.generator.constant.GroupEnum
import com.itdct.onflow.generator.model.ClassModel
import com.itdct.onflow.generator.model.CompareResultModel
import com.itdct.onflow.generator.model.FieldModel

/**
 * @author Zhouwx
 * @date 2025/8/13 17:08:53
 * @version 1.0
 * @description
 */
class ControllerTemplate(classModel: ClassModel, generatorConfig: GeneratorConfig) : BaseTemplate(classModel, generatorConfig) {
    override fun render(): String {
        return """
${uuidPrint()}
package ${classModel.packageName}.controller

import com.itdct.onflow.core.type.Add
import com.itdct.onflow.core.type.Delete
import com.itdct.onflow.core.type.Detail
import com.itdct.onflow.core.type.Update
import com.itdct.onflow.core.type.Page
import com.itdct.onflow.core.vo.KeyLabelValueVo
import com.itdct.onflow.core.vo.RespPageVo
import com.itdct.onflow.core.vo.RespVo
import ${classModel.packageName}.qo.${classModel.className}EditQo
import ${classModel.packageName}.qo.${classModel.className}SearchQo
import ${classModel.packageName}.service.${classModel.className}Service
import ${classModel.packageName}.vo.${classModel.className}DetailVo
import ${classModel.packageName}.vo.${classModel.className}ListVo
import com.itdct.onflow.system.common.base.BaseSysController
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.http.MediaType
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*

/**
 * @author ${generatorConfig.authorName}
 * @date ${getDateString()}
 * @version 1.0
 * @description ${classModel.classUsage}接口控制
 */
@Tag(name = ${classModel.className}Controller.moduleName)
@RestController
@RequestMapping(value = ["/${classModel.classNameLowCamel}"], produces = [MediaType.APPLICATION_JSON_VALUE], method = [RequestMethod.POST])
class ${classModel.className}Controller(
    val ${classModel.classNameLowCamel}Service: ${classModel.className}Service
) : BaseSysController() {
    companion object {
        const val moduleName = "${classModel.classUsage}"
    }

    @Operation(summary = moduleName + "添加")
    @PostMapping("/add.${generatorConfig.apiSuffix}")
    fun add(@RequestBody @Validated(Add::class) qo: ${classModel.className}EditQo): RespVo<Long> {
        return ${classModel.classNameLowCamel}Service.add(qo, getContext())
    }

    @Operation(summary = moduleName + "更新")
    @PostMapping("/update.${generatorConfig.apiSuffix}")
    fun update(@RequestBody @Validated(Update::class) qo: ${classModel.className}EditQo): RespVo<Unit> {
        return ${classModel.classNameLowCamel}Service.update(qo, getContext())
    }

    @Operation(summary = moduleName + "删除")
    @PostMapping("/delete.${generatorConfig.apiSuffix}")
    fun delete(@RequestBody @Validated(Delete::class) qo: ${classModel.className}EditQo): RespVo<Unit> {
        return ${classModel.classNameLowCamel}Service.delete(qo, getContext())
    }

    @Operation(summary = moduleName + "详情")
    @PostMapping("/detail.${generatorConfig.apiSuffix}")
    fun detail(@RequestBody @Validated(Detail::class) qo: ${classModel.className}SearchQo): RespVo<${classModel.className}DetailVo> {
        return ${classModel.classNameLowCamel}Service.detail(qo, getContext())
    }

    @Operation(summary = moduleName + "列表")
    @PostMapping("/page.${generatorConfig.apiSuffix}")
    fun page(@RequestBody @Validated(Page::class) qo: ${classModel.className}SearchQo): RespPageVo<${classModel.className}ListVo> {
        return ${classModel.classNameLowCamel}Service.page(qo, getContext())
    }
    
${rangeStart("selectFunctions")}
${selectFunctions()} 
${rangeEnd("selectFunctions")}
}
        """.trimIndent()
    }

    override fun onModify(compareResultModel: CompareResultModel, content: String): String {
        var content = content
        val addForSelectFields = compareResultModel.addForSelect
        val addIndex = content.indexOf(rangeEnd("selectFunctions"))
        content = insertFieldListContent(content, addForSelectFields, addIndex, { index, fieldModel -> selectFunctionContent(fieldModel) })

        val delForSelect = compareResultModel.delForSelect
        content = deleteRangeFunctionCode(content, "selectFunctions", delForSelect, { fieldModel -> selectFunctionContent(fieldModel) })
        return content
    }

    private fun selectFunctions(): String {
        return classModel.fieldList.filter {
            it.forSelect
        }.map {
            selectFunctionContent(it)
        }.joinToString("\n")
    }

    private fun selectFunctionContent(it: FieldModel) = """
    |    @Operation(summary = moduleName + "${it.comment}下拉选")
    |    @PostMapping("/select${it.nameBigCamel}List.${generatorConfig.apiSuffix}")
    |    fun select${it.nameBigCamel}List(@RequestBody qo: ${classModel.className}SearchQo): RespVo<List<KeyLabelValueVo>> {
    |        return ${classModel.classNameLowCamel}Service.select${it.nameBigCamel}List(qo, getContext())
    |    }
    |    
                """.trimMargin()

    override fun belongGroup(): GroupEnum {
        return GroupEnum.BACKEND
    }

    override fun subModuleName(): String {
        return "service"
    }

    override fun getFolderFileName(): String {
        return "controller/${classModel.className}Controller.kt"
    }

}